window.MoonConst = {};
MoonConst.COMPLETE="complete";
MoonConst.SURE="sure";
MoonConst.CANCEL="cancel";
MoonConst.ADD="add";
MoonConst.REMOVE="remove";
MoonConst.EVENT_WARN="event warn";
MoonConst.EVENT_ADD_REMOVE_NUM="event add remove num";
MoonConst.EVENT_CONTROL="event control";
MoonConst.EVENT_DOWN="event down";
MoonConst.EVENT_MOVE="event move";
MoonConst.EVENT_UP="event up";

MoonConst.WHITE=cc.color(255,255,255);
MoonConst.BLACK=cc.color(0,0,0);
MoonConst.RED=cc.color(255,0,0);
MoonConst.RED2=cc.color(128,0,0);
MoonConst.RED3=cc.color(64,0,0);
MoonConst.GREEN=cc.color(0,128,0);
MoonConst.GREEN2=cc.color(0,64,0);
MoonConst.GREEN3=cc.color(0,200,0);
MoonConst.YELLOW=cc.color(255,205,0);
MoonConst.YELLOW2=cc.color(255,153,0);
MoonConst.YELLOW3=cc.color(255,128,0);
MoonConst.BLUE=cc.color(0,128,192);
MoonConst.BLUE2=cc.color(0,128,255);
MoonConst.BLUE3=cc.color(0,128,128);
/**把官方的LOGO改成自己的*/
cc._loadingImage=""
cc._fpsImage=cc._loaderImage=cc._loadingImage
/**
 * UI节点
 * BasicNode：基础节点
 * LabelNode：Label节点
 * ShapeNode：形状节点（圆形,方形）
 * PhysicsNode：物理形状节点
 * */
cc.Vec2=cc.v2=cc.p;
cc.Node.EventType={
	TOUCH_START:'touch start',
	TOUCH_MOVE:'touch move',
	TOUCH_END:'touch end',
	TOUCH_CANCEL:'touch cancel',
}
cc.find=function(name,node){
	for(let i=0;i<node.children.length;i++){
		let n=node.children[i];
		if(n.name==name) return n;
	}
	return null;
}
//使用此文件时必须在最开头调用初始化函数
cc.init=function(thisObj){
	cc.winSize=cc.director.getWinSize();
	cc.addUpdate(thisObj);
	cc.addEvent(thisObj);
    cc.eventData=thisObj;
}
cc.addEvent=function(thisObj){
	thisObj.events={};
	cc.eventManager.addListener({
        event: cc.EventListener.TOUCH_ONE_BY_ONE,
        onTouchBegan: function (touch, event) {
			thisObj.sendHandler(cc.Node.EventType.TOUCH_START,touch)
            return true;
        },
        onTouchMoved: function (touch, event) {
			thisObj.sendHandler(cc.Node.EventType.TOUCH_MOVE,touch)
            return true;
        },
        onTouchEnded: function (touch, event) {
			thisObj.sendHandler(cc.Node.EventType.TOUCH_END,touch)
            return true;
        }
    }, thisObj);
	thisObj.sendHandler=function(type,touch){
		const x = touch.getLocation().x
        const y = touch.getLocation().y
		const v2=new cc.Vec2(x,y);
		for(let id in thisObj.events){
			let arr=thisObj.events[id];
			for(let i=0;i<arr.length;i++){
				let o=arr[i];
				if(o.type==type){
					let target=o.target;//以锚点开始计算x,y
					let [x,y,width,height]=[target.x, target.y,target.width, target.height];
					if(target.isCenter){
						x-=width/2;
						y-=height/2;
					}
					let rect = new cc.Rect(x,y,width,height);
					if(cc.rectContainsPoint(rect,v2)){
						touch.target=target;
						o.handler(touch);
					}
				}
			}
		}
	}
}
/**循环函数*/
cc.addUpdate=function(thisObj){
	if(thisObj.update){
		thisObj.scheduleUpdate(thisObj.update);
	}
}
class Layer extends cc.LayerColor{
    set position(value){
		this.x=value.x;
		this.y=value.y;
	}
	get position(){
		return cc.v2(this.x,this.y);
	}
	/**帧听事件*/
	on(type,handler,thisObj){
		//console.log(this.__instanceId,thisObj);
		if(!thisObj.events[this.__instanceId])thisObj.events[this.__instanceId]=[];
		thisObj.events[this.__instanceId].push({type:type,target:this,handler:handler});
		this.thisObj=thisObj;
	}
	/**删除事件*/
	off(type,handler,thisObj){
		let datas=thisObj.events[this.__instanceId];
		if(datas){
			for(let i=0;i<datas.length;i++){
				let da=datas[i];
				if(da.type==type){
					datas.splice(i,1);
					break;
				}
			}
		}
	}
}
class BasicNode extends cc.DrawNode {
    /**设置坐标*/
    moveTo(x=0,y=0){
        this.x=x;this.y=y;
    }
	setContentSize(w,h){
		this.width=w;
		this.height=h;
	}
    /**设置透明度 v=[0-1] 无效果*/
    set alpha(v){
        this.opacity=v*255;
    }
    /**设置可视 v=true/false*/
    set visible(v){
        super.visible=v;
    }
	set active(v){
		this.visible=v;
	}
	set color(value){
		super.color=value;
	}
	set angle(value){
		this.rotation=value;
	}
	set position(value){
		this.x=value.x;
		this.y=value.y;
	}
	get position(){
		return cc.v2(this.x,this.y);
	}
	/**帧听普通事情与鼠标事件*/
	on(type,handler,thisObj){
		//console.log(this,thisObj,this.__instanceId);
		if(!thisObj.events[this.__instanceId])thisObj.events[this.__instanceId]=[];
		thisObj.events[this.__instanceId].push({type:type,target:this,handler:handler});
		this.thisObj=thisObj;
	}
	/**删除*/
	off(type,handler,thisObj){
		let datas=thisObj.events[this.__instanceId];
		if(datas){
			for(let i=0;i<datas.length;i++){
				let da=datas[i];
				if(da.type==type){
					datas.splice(i,1);
					break;
				}
			}
		}
	}
	/**发布听事件*/
	emit(type,data){
		let thisObj=this.thisObj;
		if(!thisObj)return;
		for(let id in thisObj.events){
			let arr=thisObj.events[id];
			for(let i=0;i<arr.length;i++){
				let o=arr[i];
				if(o.type==type){
					o.handler(data);
				}
			}
		}
		let handler=this[type];
		if(handler) handler(data);
	}
}
class LabelNode extends BasicNode{
    constructor(value,size=40,scale=0.5){
        super();
        this.label = new cc.LabelTTF(value, "arial", size);
		this.addChild(this.label);
        this.setFontScale(size,scale);
    }
    set string(value){
        this.label.setString(value);
    }
    get string(){
        return this.label.getString();
    }
	set color(value){
		this.label.setColor(value);
	}
    set lineHeight(val){
        this.label.lineHeight=val
    }
    /**设置字体大小与缩放比例*/
    setFontScale(size,scale){
        this.label.setFontSize(size);
        //this.label.lineHeight=size;
        this.scale=scale;
    }
}
/**ShapeNode：形状节点（圆形,方形）*/
class ShapeNode extends BasicNode{
    initGraphics(){
             
    }
    /**圆形*/
    createCircle(r,c=cc.color.WHITE){
        this.setContentSize(r*2,r*2);
        this.initGraphics();
		this.drawDot(cc.p(0,0),r,c);//接口不支持描边
		this.isCenter=true;
	}
    /**方形,画出来的方形锚点默认在中间位置*/
    createBox(wid,hei,c=cc.color.WHITE,isLine=true,isCenter=true){
		this.setContentSize(wid,hei);
        this.initGraphics();
        let [x,y,w,h]=[0,0,wid,hei];
		this.isCenter=isCenter;
		isCenter&&(x=-w/2,y=-h/2,w=w/2,h=h/2)
		if(isLine)    this.drawRect(cc.p(x,y),cc.p(w,h),c,2,cc.color.BLACK);//有描边
		else		  this.drawRect(cc.p(x,y),cc.p(w,h),c,0.001);//没描边
    }
    /**三角形，h表示高*/
    createTriangle(r,h=0,c=cc.color.WHITE,isLine=true){
        this.setContentSize(r*2,r*2+h);
        this.initGraphics();
		if(isLine)    this.drawPoly([cc.p(r,0),cc.p(-r,0), cc.p(0,r+h)],c,2,cc.color.BLACK);//有描边
		else		  this.drawPoly([cc.p(r,0),cc.p(-r,0), cc.p(0,r+h)],c,0.001);//没描边
    }
    /**多角形，可画三角形四边形凌型*/
    createPolygon(array,c=cc.color.WHITE,lineWidth=2){
		this.setContentSize(100,100);
        this.initGraphics();
        this.drawPoly(array,c,lineWidth);
    }
    /**请除直接调用clear()就可以*/
    clear(){
        super.clear();
		this.isCenter=false;
    }
    /**创建网格
     * rect={x:10,y:10,width:100,height:100}
     * x为x轴数量,width为宽度
     * y为y轴数量,height为高度
    */
    createGridding(rect,lc=cc.color.BLACK,size=1){
        this.setContentSize(rect.width,rect.height);
        this.initGraphics();
        var disx=rect.width/(rect.x-1);
        var disy=rect.height/(rect.y-1);
        var xNum=rect.x;
        var yNum=rect.y;
        //cc.log(disx,disy,xNum,yNum);
        for(var i=0;i<xNum;i++){
            let s=new cc.Vec2(0,i*disy);
			let e=new cc.Vec2(rect.width,i*disy);
			this.drawSegment(s,e,size,lc);
        }
        for(i=0;i<yNum;i++){
            let s=new cc.Vec2(i*disx,0);
            let e=new cc.Vec2(i*disx,rect.height);
			this.drawSegment(s,e,size,lc);
        }
    }
    /**创建多条线段
     * array=[[0,0],[100,100]]
    */
   createMoreLine(array,lc=cc.color.BLACK,size=1){
        this.initGraphics();
        for(var i=0;i<array.length;i+=2){
            var prev=array[i];
            var next=array[i+1];
			prev=cc.Vec2(prev[0],prev[1]);
			next=cc.Vec2(next[0],next[1]);
			let line=new ShapeNode();
			this.addChild(line);
			line.drawSegment(
				prev,// 起点
				next, // 终点
				size, // 线粗
				lc // 颜色
			 );
        }
    }
    /**创建一条线段多个拐点
     * array=[[0,0],[100,100]]
    */
   createMoreLine2(array,lc=cc.color.BLACK,size=1){
        this.initGraphics();
        for(var i=0;i<array.length-1;i++){
            var prev=array[i];
            var next=array[i+1];
			prev=cc.Vec2(prev[0],prev[1]);
			next=cc.Vec2(next[0],next[1]);
			//console.log(prev,next);
			this.drawSegment(
				prev,// 起点
				next, // 终点
				size, // 线粗
				lc // 颜色
			 );
        }
    }
    /**可制绘不重复的一条直线 */
    drawLine(staPos,endPos,lc=cc.color.BLACK,size=1){
        this.clear();
        this.initGraphics();
        this.x=staPos.x;this.y=staPos.y;
		this.drawSegment(
			staPos,// 起点
			endPos, // 终点
			size, // 线粗
			lc // 颜色
 		);
    }
    /**设置填充色*/
    setFillColor(c){
        
    }
}
//-------------提示与控制组件---------------------
class LoadNode extends BasicNode{
    constructor(thisObj){
        super();
		this.setThisObj(thisObj)
        this.child=null;
    }
	setThisObj(thisObj){
		this.thisObj=thisObj;
	}
    /**设置孩子节点*/
    setChild(value){
        this.child=value;
    }
    /**设置child的位置与this位置一样(例如ControlBar就需要他们位置一样) */
    setPositionChildEqual(v2){
        this.position=v2;
    }
	/**计算两点间的距离*/
	posToPosDistance(v1,v2){
		let x=v1.x-v2.x;
		let y=v1.y-v2.y;
		return Math.hypot(x,y);
	}
}
class ButtonNode extends LoadNode{
    constructor(data){
        super();
        if(!data)return;
        let color=data.color||MoonConst.GREEN3;
       
        let node=new ShapeNode();
		if(data.radius>0){//圆形按钮
            node.createCircle(data.radius,color);
        }else{//方形按钮
            node.createBox(data.width,data.height,color,false);
        }
        var label = new LabelNode(data.label||'按钮',data.size||30);
        label.color=data.labelColor||MoonConst.BLACK;
        this.label=label;
        node.addChild(label);
        this.addChild(node);
        this.setContentSize(node.width,node.height);
        this.isCenter=true;
        this.node=node;

        this.thisObj=cc.eventData;
        this.on(cc.Node.EventType.TOUCH_START,this.onStart.bind(this), this.thisObj);
        this.on(cc.Node.EventType.TOUCH_END,this.onEnd.bind(this), this.thisObj);
        this.on(cc.Node.EventType.TOUCH_CANCEL,this.onEnd.bind(this), this.thisObj);
    }
    setLabel(value){
        this.label.string=value;
    }
    setFontSize(value){
        this.label.setFontScale(value)
    }
    onStart(e){
        this.scale=1.1;
    }
    onEnd(e){
        this.scale=1;
    }
}
/**有确定与取消的二次确认框 */
class Warn extends LoadNode {
    constructor(message){
        super();
        this.message=message;
    }
    loadPrefabCom(){
        var btn1=cc.find("btn_sure",this.child);
        var btn2=cc.find("btn_cancel",this.child);
        btn1.on(cc.Node.EventType.TOUCH_END,this.onClick,this.thisObj);
        btn2.on(cc.Node.EventType.TOUCH_END,this.onClick,this.thisObj);
        var title=cc.find("title",this.child).getComponent(cc.Label);
        title.string=this.message;
    }
    onClick(e){
        var btn=e.target;
        this.emit(MoonConst.EVENT_WARN,btn.name.split("_")[1]);
        this.destroy();
    }
}
/** 有加与减的组件[-][ 2 ][+]*/
class AddRemoveNum extends LoadNode {
    constructor(){
        super();
        this.count=1;
        this.setMinMax();
    }
    setMinMax(min=1,max=99){
        this.min=min;
        this.max=max;
    }
    setChild(value){
        //cc.log(value)
        super.setChild(value);
        var btn1=cc.find("btn_add",this.child);
        var btn2=cc.find("btn_remove",this.child);
        btn1.on(cc.Node.EventType.TOUCH_END,this.onClick.bind(this),this.thisObj);
        btn2.on(cc.Node.EventType.TOUCH_END,this.onClick.bind(this),this.thisObj);
        this.input=cc.find("input",this.child).getComponent(cc.Label);
        this.updateCount();
    }
    updateCount(){
        if(this.input){
            this.input.string=this.count;
        }
    }
    onClick(e){
        var btn=e.target;
        var type=btn.name.split("_")[1]
        if(type==MoonConst.ADD){
            if(this.count<this.max) this.count++;
        }else{
            if(this.count>this.min) this.count--;
        }
        this.updateCount();
        this.emit(MoonConst.EVENT_ADD_REMOVE_NUM,this.count);
    }
}
/** 游戏的遥杆 可以使用加载的也可以使用场景中的*/
class ControlBar extends LoadNode {
    loadPrefabCom(){
        this.setChild(this.child);
    }
    setChild(value){
        super.setChild(value);
        this.isLeftRight=false;//是否左右方向移动
        this.bg=cc.find("controlBg",this.child);
        this.bar=cc.find("bar",this.child);
        this.distance=this.bg.width/2;
        this.child.on(cc.Node.EventType.TOUCH_START,this.startDrag.bind(this),this.thisObj);
    }
    /**点下去*/
    startDrag(e){
        var node=e.target;
        node.on(cc.Node.EventType.TOUCH_MOVE,this.moveDrag.bind(this),this.thisObj);
        node.on(cc.Node.EventType.TOUCH_END,this.endDrag.bind(this),this.thisObj);
        node.on(cc.Node.EventType.TOUCH_CANCEL,this.endDrag.bind(this),this.thisObj);
    }
    /**拖动 */
    moveDrag(e){
        var node=this.bar;
        var size=cc.winSize;
        var moveV2=e.getLocation();
        var dx=moveV2.x-this.child.x;
        var dy=moveV2.y-this.child.y;
        var dis=this.distance;
        var v2=cc.v2(dx,dy);
		var ds=Math.sqrt(dx*dx+dy*dy);
        if(ds<=dis){//在圈内
           //直接使用v2
        }else{//在圈外
            dx=dx/ds*dis;
            dy=dy/ds*dis;
            v2=cc.v2(dx,dy);
        }
        if(this.isLeftRight){
            v2.y=0;
        }
        node.position=v2;
        let r=this.distance>>2;
        let x=0,y=0;
        if(this.posToPosDistance(node.position,new cc.v2(0,0))>r){
            if(Math.abs(v2.x)>Math.abs(v2.y)){//左右移动
                y=0;
                x=v2.x>0?1:-1;
            }else{//上下移动
                y=v2.y>0?1:-1;
                x=0;
            }
        }
        var s=cc.v2(x,y);
        this.emit(MoonConst.EVENT_CONTROL,{p:v2,s:s});//p是正常位置，s是表示方向上(0,1)下(0,-1)左(-1,0)右(1,0)
    }
    /**放开*/
    endDrag(e){
        var node=this.bar;
        node.position=cc.v2(0,0);
        node.off(cc.Node.EventType.TOUCH_MOVE,this.moveDrag.bind(this),this.thisObj);
        node.off(cc.Node.EventType.TOUCH_END,this.endDrag.bind(this),this.thisObj);
        node.off(cc.Node.EventType.TOUCH_CANCEL,this.endDrag.bind(this),this.thisObj);
        this.emit(MoonConst.EVENT_CONTROL,{p:cc.v2(0,0),s:cc.v2(0,0)});
    }
}
/** 自由拖动 可以使用加载的也可以使用场景中的*/
class FreeDrag extends LoadNode {
    setChild(value){
        super.setChild(value);
        this.open();
    }
    open(){
        this.child.on(cc.Node.EventType.TOUCH_START,this.startDrag.bind(this),this.thisObj);
    }
    close(){
        this.child.off(cc.Node.EventType.TOUCH_START,this.startDrag.bind(this),this.thisObj);
    }
    /**点下去*/
    startDrag(e){
        var node=e.target;
        var size=cc.winSize;
        var moveV2=e.getLocation();
        var dx=moveV2.x-(size.width/2+this.x);
        var dy=moveV2.y-(size.height/2+this.y);
        this.startPos=cc.v2(dx-node.x,dy-node.y);
		node.zIndex=node.parent.childrenCount;
		this.emit(MoonConst.EVENT_DOWN,node);
		if(node.parent&&node.parent.on){
			node=node.parent;
		}
        node.on(cc.Node.EventType.TOUCH_MOVE,this.moveDrag.bind(this),this.thisObj);
        node.on(cc.Node.EventType.TOUCH_END,this.endDrag.bind(this),this.thisObj);
        node.on(cc.Node.EventType.TOUCH_CANCEL,this.endDrag.bind(this),this.thisObj);
		this.startDrag=true;
        
    }
    /**拖动*/
    moveDrag(e){
		if(!this.startDrag)return;
        var node=this.child;
        var size=cc.winSize;
        var moveV2=e.getLocation();
        var dx=moveV2.x-(size.width/2+this.x);
        var dy=moveV2.y-(size.height/2+this.y);
        var v2=cc.v2(dx-this.startPos.x,dy-this.startPos.y);
        node.position=v2;
        this.emit(MoonConst.EVENT_MOVE,node);
    }
    /**放开*/
    endDrag(e){
        var node=e.target;
        node.off(cc.Node.EventType.TOUCH_MOVE,this.moveDrag.bind(this),this.thisObj);
        node.off(cc.Node.EventType.TOUCH_END,this.endDrag.bind(this),this.thisObj);
        node.off(cc.Node.EventType.TOUCH_CANCEL,this.endDrag.bind(this),this.thisObj);
        this.emit(MoonConst.EVENT_UP,node);
		this.startDrag=false;
    }
}
/** 自由滑动 可以使用加载的也可以使用场景中 muq*/
class FreeMove extends LoadNode {
    distance=20;
    setChild(value){
        super.setChild(value);
        this.open();
    }
    open(){
        this.child.on(cc.Node.EventType.TOUCH_START,this.startDrag.bind(this),this.thisObj);
    }
    close(){
        this.child.off(cc.Node.EventType.TOUCH_START,this.startDrag.bind(this),this.thisObj);
    }
    /**点下去*/
    startDrag(e){
        var node=e.target;
        this.startV2=e.getLocation();
        node.on(cc.Node.EventType.TOUCH_MOVE,this.moveDrag.bind(this),this.thisObj);
        node.on(cc.Node.EventType.TOUCH_END,this.endDrag.bind(this),this.thisObj);
        node.on(cc.Node.EventType.TOUCH_CANCEL,this.endDrag.bind(this),this.thisObj);
        this.emit(MoonConst.EVENT_DOWN,node);
    }
    /**拖动*/
    moveDrag(e){
        this.sendEmit(MoonConst.EVENT_MOVE,e);
    }
    /**放开*/
    endDrag(e){
        var node=e.target;
        node.off(cc.Node.EventType.TOUCH_MOVE,this.moveDrag.bind(this),this.thisObj);
        node.off(cc.Node.EventType.TOUCH_END,this.endDrag.bind(this),this.thisObj);
        node.off(cc.Node.EventType.TOUCH_CANCEL,this.endDrag.bind(this),this.thisObj);
        this.sendEmit(MoonConst.EVENT_UP,e);
    }
    sendEmit(eventType,e){
        var size=cc.winSize;
        var endV2=e.getLocation();
        var r=this.distance;
        var dx=endV2.x-this.startV2.x;
        var dy=endV2.y-this.startV2.y;
        var v2=cc.v2(dx,dy);
        let x=0,y=0;
        if(this.posToPosDistance(this.startV2,endV2)>r){
            if(Math.abs(v2.x)>Math.abs(v2.y)){//左右移动
                y=0;
                x=v2.x>0?1:-1;
            }else{//上下移动
                y=v2.y>0?1:-1;
                x=0;
            }
            var s=cc.v2(x,y);
            this.emit(eventType,{p:v2,s:s});//p是正常位置，s是表示方向上(0,1)下(0,-1)左(-1,0)右(1,0)
        }
    }
}
/**加载图片 */
class LayerImage extends Layer{
    constructor(data){
        super();
        this.loadImage(data.url);
    }
    loadImage(url){
        let size=cc.size(cc.winSize.width,cc.winSize.height);
        var bg = new cc.Scale9Sprite(url);
        bg.addLoadedEventListener((e)=>{
            bg.scaleX=size.width/bg.width;
            bg.scaleY=size.height/bg.height;
        })
        bg.setPosition(cc.v2(size.width/2,size.height/2))
        this.addChild(bg);
    }
}
class ButtonImage extends ButtonNode{
    constructor(data){
        super();
        var sprite=new cc.Scale9Sprite(data.url);
        this.setContentSize(sprite.width,sprite.height);//如果资源有提早加载则有宽高
        this.addChild(sprite);
        sprite.addLoadedEventListener((e)=>{
            if(data.width)sprite.width=data.width;
            if(data.height)sprite.height=data.height;
            this.setContentSize(sprite.width,sprite.height);
            this.isCenter=true;

            if(data.callBack)data.callBack(this);
        })
       
        var label = new LabelNode(data.label||'按钮',data.size||30);
        label.color=data.labelColor||MoonConst.BLACK;
        this.label=label;
        this.addChild(label);

        this.thisObj=cc.eventData;
        this.on(cc.Node.EventType.TOUCH_START,this.onStart.bind(this), this.thisObj);
        this.on(cc.Node.EventType.TOUCH_END,this.onEnd.bind(this), this.thisObj);
        this.on(cc.Node.EventType.TOUCH_CANCEL,this.onEnd.bind(this), this.thisObj);
    }
}
class Scale9Image extends BasicNode{
    constructor(data){
        super();
        var sprite=new cc.Scale9Sprite(data.url);
        this.setContentSize(sprite.width,sprite.height);
        this.addChild(sprite);
        this.sprite=sprite;
        sprite.addLoadedEventListener((e)=>{
            this.isCenter=true;
            if(data.width)sprite.width=data.width;
            if(data.height)sprite.height=data.height;
            this.setContentSize(sprite.width,sprite.height);
            if(data.callBack)data.callBack(this);
        })
    }
    setSize(data){
        if(data.width)this.sprite.width=data.width
        if(data.height)this.sprite.height=data.height
        this.setContentSize(this.sprite.width,this.sprite.height);
    }
}
//-------------数据结构---------------------
class BasicData extends Object{
    constructor(){
        super();
        this.nodes=[];
    }
}
/**数据集*/
class DataContent extends BasicData{
    constructor(){
        super();
        this.index=0;
    }
    setNodes(nodes){
        this.nodes=nodes;
    }
    addNode(n){
        n.parent=null;
        if(this.nodes.indexOf(n)==-1){
            this.nodes.push(n);
        }
    }
    removeNode(n){
        if(i>=0){
            this.nodes.splice(i,1);
        }
    }
    hasNode(n){
        return this.nodes.indexOf(n)>=0;
    }
    reset(){
        this.index=0;
    }
    next(){
        return this.nodes[this.index++];
    }
    hasNext(){
        return this.index < this.nodes.length && this.nodes.length > 0;
    }
}
/**数据树*/
class DataTree extends BasicData{
    constructor(data){
        super();
        this.index=0;
        this.data=data;
        this.parent=null;
    }
    getData(){  
        return this.data;  
    }  
    setData(data){  
        this.data = data;  
    }
    getParent(){  
        return this.parent;  
    }  
    //添加父级节点
    setParent(parent){  
        this.parent = parent;  
    }  
    //添加孩子节点  
    add(node){
        node.setParent(this);
        this.nodes.push(node);
    }  
    //删除孩子节点  
    remove(node){
        var index=this.nodes.indexOf(node)
        if(index!=-1)this.nodes.splice(index,1);
    }  
    //取得所有孩子节点  
    getChilds(){  
        return this.nodes;  
    }
}
//-----------创建组件---ControlBar-------
cc.createControlBar=function(thisObj,outSide=50,inSide=30,outColor=cc.color(200,200,200,150),inColor=cc.color(50,50,50,100)){
	var content=new BasicNode();
	content.setContentSize(cc.winSize.width,cc.winSize.height);
	content.isCenter=true;
	thisObj.addChild(content);

	var controlBg=new ShapeNode();
	controlBg.name='controlBg';
	controlBg.createCircle(outSide,outColor);
	content.addChild(controlBg);

	var bar=new ShapeNode();
	bar.name='bar';
	bar.createCircle(inSide,inColor);
    bar.opacity=100;
	content.addChild(bar);

	var controlBar=new ControlBar();
	controlBar.setThisObj(thisObj);
	controlBar.setChild(content);
	return controlBar;
}
cc.toColor=(str)=>{
    return cc.hexToColor(str);
}
//-----开始运行cocos2d---
cc.startCoco2d=function(callBack,resources){
    var canvas = document.getElementById('canvas');
    if(!canvas){
        canvas=document.createElement('canvas');
        canvas.id='canvas';
        document.body.appendChild(canvas);
        document.body.style.margin=0;//全屏不留边
    }
    canvas.style.width='100%';
    canvas.style.height='100%'
    canvas.width = window.innerWidth;
    canvas.height = window.innerHeight;
    cc.game.onStart = function () {
        var MyScene = cc.Scene.extend({
            onEnter: function () {
                this._super();
                cc.init(this);
                callBack(this)
            },
            update(dt) {
                
            }
        });
        cc.LoaderScene.preload(resources, function () {
            cc.director.runScene(new MyScene());
        }, this);
    };
    cc.game.run("canvas");
}

//--------
/**
 * 
 * ----形状-----
 1、  构造： var Draw= new cc.DrawNode();
2、  画线:
Draw.drawSegment(
           cc.p(0, 0),// 起点
           cc.p(0,100), // 终点
           10, // 线粗
           cc.color(0,255, 255, 255) // 颜色
);

3、  画圆:
Draw.drawDot(
           cc.p(200,200), // 圆点
           100, // 半径
           cc.color(255,255, 255, 125) // 圆的颜色
);

4、  画矩形
Draw.drawRect(
           cc.p(20,20), // 起点
           cc.p(200,200), // 起点的对角点
           cc.color(255,0, 0, 125), // 填充颜色
           10, // 线粗
           cc.color(255,255, 255, 255) // 线颜色
);

5、  画多边形
Draw.drawPoly(
           [cc.p(0, 0),cc.p(0, 100), cc.p(200, 200)], // 多边形的点
           cc.color(255,255, 255, 125), // 填充颜色
           10, // 线粗
           cc.color(111,111, 111, 255) // 线颜色
);

6、  画一截一截的圆
Draw.drawCircle(
           cc.p(200,200), // 圆心
           100, // 半径
           0, // 画圆的起始角度
           20, // 这个圆由多少截线段组成
           false, // 是否显示圆心到开始角度的线
           10, // 线粗
           cc.color(255,255, 255, 255) // 线条颜色
);
————————————————
		----文本-----
 1、  创建
var text = new cc.LabelTTF(“这是一段文字” [, 文字的配置, 大小] );
EG:
var text = new cc.LabelTTF(“哈哈，文字哦~”, "Arial",24); // 创建了一段Arail，大小为24的字体

2、  改变文字内容
text.setString(“更改的内容啊~”);

3、 设置颜色
label.setColor(cc.color(255, 0, 0, 255)); // 将字体改为红色

4、 设置文字大小
label.setFontSize(100); //设置为100号字体

5、  文字对齐
label.textAlign = cc.TEXT_ALIGNMENT_CENTER;// 居中
cc.TEXT_ALIGNMENT_LEFT; // 居左
cc.TEXT_ALIGNMENT_RIGHT; // 居右

PS:
单行的文字，是无法看出textAlign的效果的说~。
用”\n”换行试试~

6、  文字显示范围
label.setDimensions(width, height); // 文字显示的范围

7、  忽略anchor的设置
label.ignoreAnchor = true; // 设置后，label的起始点在左下角

8、  文字定义：
var text = new cc.LabelTTF(“文字”, def);
def 是这样定义:
var def = new cc.FontDefinition(); // 声明文字定义
def.fontName = “宋体,微软雅黑”; // 字体
def.fontSize = 24; // 字号大小
def.textAlign = cc.TEXT_ALIGNMENT_CENTER; // 文字对齐
def.fillStyle = cc.color(“#ffffff”); // 字体(内部)颜色
def.strokeEnabled = true; // 开启文字描边效果
def.strokeStyle = cc.color(“#ffeeee”); // 描边的颜色
def.lineWidth = 3; // 字体的宽度
defadowEnabled = true; // 开启阴影效果
def.shadowOffsetX = 12; // 阴影X轴效果
def.shadowOffsetY = 12; // 阴影Y轴效果

————————————————
		----Sprite----
1.      普通创建
var sprite = new cc.Sprite(“从loader加载的资源名称”);

2.      设置中点
sprite. setAnchorPoint(0~1, 0~1); // x、y的坐标
或者:
sprite.setAnchorPoint(cc.p(x, y)); // 同上

3.      x/y坐标(图片中点的坐标)
sprite.setPosition(x, y);
或者
sprite.setPosition(cc.p(x, y));

4.      缩放
sprite. setScale(0.5); // 变为原本的0.5
或
sprite.setScale(0.5, 1); // x轴缩小到0.5，y轴保持不变

5.      图片翻转
sprite.flippedX = true; // X轴翻转
sprite.flippedY = true; // Y轴翻转

6.      设置透明
sprite.setOpacity (175); // 透明度 0 ~255，0是全透明

7.      颜色过滤效果
sprite.setColor(cc.color(0,255,255, 255)); // 蓝色过滤效果

8.      获取图片的box信息
var box = sprite.getBoundingBox(); // 包含x/y/width/height

9.      读取图片的某一片段
sprite.setTextureRect(cc.rect(x, y, width, height));//cc.rect的起点在左下角
// 从图片的(x,y)点开始，截取width、height部分显示
或者：
varsprite = new cc.Sprite(“res.png”, cc.rect(x,y, w, h)); // 解析同上

10.   更换图片资源
Sprite.setTexture(“更换的图片名称”); // 注意，如果设置过textureRect，可能因为图片坐标、大小变化，而看不见新的图片
或:
// 很麻烦的说~
var texture = newcc.Texture2D();
texture.initWithElement(img);//img 是cc.loader.loadImg的 img
texture.handleLoadedTexture();
sprite.setTexture(texture);
或:
// 在setTexure的源码里，有这么一种写法
// 就是不知道addImage的图片，是不是一定要先经过cc.loader的了~
var texture = cc.textureCache.addImage(“图片名称”);
sprite.setTexture(texture);
// 后边可不要~
var size = texture.getContentSize();
sprite.setTextureRect(cc.rect(0,0,size.width, size.height));

11.   重设zIndex
parent. reorderChild(sprite, zIndex); // 找到父亲，重新设置zIndex
————————————————
 * 
 */